﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DCS.Business.Manager;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using DCS.DataProvider;
using System.Configuration;
using DCS.Business.Model;
using System.Text.RegularExpressions;
using DCS.Business.Model.PublishUsage;
using System.Text;

namespace DCS.DataService
{
    public class BOProxy
    {
        #region Members

        public static readonly BOProxy Instance = new BOProxy();
        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        static PRLMessageManager prlmanager;
        static LDMMessageManager ldmmanager;
        static PublishManager pblmanager;

        static string[] BasicRole = ConfigurationManager.AppSettings["BasicRole"].Split('|');

        #endregion

        #region Ctor.

        private BOProxy()
        {
            IUnityContainer myContainer = new UnityContainer();
            UnityConfigurationSection section
              = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Containers["Data"].Configure(myContainer);

            IDataProvider dp = myContainer.Resolve<IDataProvider>();

            prlmanager = new PRLMessageManager(dp);
            ldmmanager = new LDMMessageManager(dp);
            pblmanager = new PublishManager(dp);
        }

        #endregion

        #region Publish

        static readonly Regex rg2Char = new Regex("[A-Z]{2}$");
        static readonly Regex rg3Char = new Regex("[A-Z]{3}$");
        static readonly Regex rg35NumChar = new Regex("[0-9A-Z]{3,5}$");
        static readonly Regex rg3Num = new Regex("[0-9]{3}$");
        static readonly Regex rgYYYYMMDD = new Regex("[0-9]{4}-[0-9]{2}-[0-9]{2}$");

        private void ValidateStringFormat(string param, string value, Regex reg)
        {
            if (!reg.IsMatch(value))
                throw new FormatException(string.Format("Parameter '{0}' should be in format '{1}'", param, reg));
        }

        private void ValidateRole(Role role, string loginsystem)
        {
            if ((role == Role.Basic) && (!BasicRole.Contains(loginsystem)))
            {
                throw new HttpRequestValidationException("Access Deny. Pls check your loginsystem field.");
            }
        }

        public List<PRLMessage> GetFQPassengers(string loginsystem, string carrier, string flightNo, string pdate, string dept, string arr)
        {
            ValidateRole(Role.Basic, loginsystem);
            ValidateStringFormat("carrier", carrier, rg2Char);
            ValidateStringFormat("flightNo", flightNo, rg35NumChar);
            ValidateStringFormat("dept", dept, rg3Char);
            ValidateStringFormat("arr", arr, rg3Char);
            ValidateStringFormat("pdate", pdate, rgYYYYMMDD);

            //modified by RenWenJie 2011-7-20
            if (Convert.ToDateTime(pdate)<=DateTime.Today.AddDays(-7))
            {
                return prlmanager.GetPassengersByOpt("SQL_GetFQPassengersHis", carrier, flightNo, DateTime.Parse(pdate), dept, arr);
            }
            else
            {
                return prlmanager.GetPassengersByOpt("SQL_GetFQPassengers", carrier, flightNo, DateTime.Parse(pdate), dept, arr);
            }
            //return prlmanager.GetPassengersByOpt("SQL_GetFQPassengers", carrier, flightNo, DateTime.Parse(pdate), dept, arr);
        }

        public List<LDMMessage> GetLDMMessage(string loginsystem, string carrier, string flightNo, string pdate, string dept, string arr)
        {
            ValidateRole(Role.Basic, loginsystem);
            ValidateStringFormat("carrier", carrier, rg2Char);
            ValidateStringFormat("flightNo", flightNo, rg35NumChar);
            ValidateStringFormat("dept", dept, rg3Char);
            ValidateStringFormat("arr", arr, rg3Char);
            ValidateStringFormat("pdate", pdate, rgYYYYMMDD);

            if (rg3Num.IsMatch(flightNo) && flightNo.Length < 4)
            {
                flightNo = "0" + flightNo;
            }

            return ldmmanager.GetLDMMessage(carrier, flightNo, DateTime.Parse(pdate), dept, arr);
        }

        public FlightPassengerInfo GetFlightPassengerInfo(string loginsystem, string carrier, string flightNo, string pdate, string dept, string arr)
        {
            ValidateRole(Role.Basic, loginsystem);
            ValidateStringFormat("carrier", carrier, rg2Char);
            ValidateStringFormat("flightNo", flightNo, rg35NumChar);
            ValidateStringFormat("dept", dept, rg3Char);
            ValidateStringFormat("pdate", pdate, rgYYYYMMDD);

            return pblmanager.GetFlightPassengerInfo(carrier, flightNo, DateTime.Parse(pdate), dept, arr);
        }

        public List<PRLMessage> GetAllPassengers(string loginsystem, string carrier, string flightNo, string pdate, string dept, string arr)
        {
            ValidateRole(Role.Basic, loginsystem);
            ValidateStringFormat("carrier", carrier, rg2Char);
            ValidateStringFormat("flightNo", flightNo, rg35NumChar);
            ValidateStringFormat("dept", dept, rg3Char);
            ValidateStringFormat("arr", arr, rg3Char);
            ValidateStringFormat("pdate", pdate, rgYYYYMMDD);

            //modified by RenWenJie 2011-7-20
            if (Convert.ToDateTime(pdate) <= DateTime.Today.AddDays(-7))
            {
                return prlmanager.GetPassengersByOpt("SQL_GetALLPassengersHis", carrier, flightNo, DateTime.Parse(pdate), dept, arr);
            }
            else
            {
                return prlmanager.GetPassengersByOpt("SQL_GetALLPassengers", carrier, flightNo, DateTime.Parse(pdate), dept, arr);
            }
        }

        public List<PRLMessage> QueryTripHistory(string surname, string givenname, string foid, string cnin)
        {
            StringBuilder sb = new StringBuilder();

            int paramCount = 0;

            if (!string.IsNullOrEmpty(foid))
            {
                paramCount++;
                sb.AppendFormat(" AND FOID = 'NI{0}'", foid);
            }

            if (!(string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(givenname)))
            {
                paramCount++;
                sb.AppendFormat(" AND PName in ('{0}{1}','{0}/{1}','{1}/{0}')", surname, givenname);
            }

            if (!string.IsNullOrEmpty(cnin))
            {
                paramCount++;
                sb.AppendFormat(" AND CNIN = '{0}'", cnin);
            }

            if (paramCount >= 1)
            {
                return prlmanager.QueryTripHistory(sb.ToString());
            }
            else
            {
                throw new ArgumentNullException("surname&givenname, foid, cnin", "至少一项不要为空嘛");
            }
        }

        #endregion

        enum Role
        {
            Basic,
            Admin
        }
    }
}